package analysis;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.objdetect.CascadeClassifier;

import utils.ImageDeted;

public class EyeDet implements IDetection {

	public ImageDeted run(ImageDeted id) {

		if (id.getNvolti() < 1)
			id.setNocchi(-1);
		else
			id = extractEye(id, "haarcascade_lefteye_2splits.xml",
					"haarcascade_righteye_2splits.xml");

		id.setSemaforo(-1);
		return id;
	}

	private ImageDeted extractEye(ImageDeted id, String filenameL,
			String filenameR) {

		CascadeClassifier eyeDetectorL = new CascadeClassifier("./src/res/"
				+ filenameR);
		CascadeClassifier eyeDetectorR = new CascadeClassifier("./src/res/"
				+ filenameL);

		MatOfRect eyeDetections = new MatOfRect();
		Rect rects = null;

		for (int i = 0; i < id.getNvolti(); i++) {

			Rect occhioDestro = new Rect(id.getVolti()[0].x
					+ id.getVolti()[0].width / 8,
					(int) (id.getVolti()[0].y + id.getVolti()[0].height / 4.5),
					id.getVolti()[0].width / 2 - id.getVolti()[0].width / 8,
					id.getVolti()[0].height / 3);

			Rect occhioSinistro = new Rect(id.getVolti()[0].x
					+ id.getVolti()[0].width / 2,
					(int) (id.getVolti()[0].y + id.getVolti()[0].height / 4.5),
					id.getVolti()[0].width / 2 - id.getVolti()[0].width / 8,
					id.getVolti()[0].height / 3);

			Core.rectangle(id.getImage(), new Point(occhioDestro.x,
					occhioDestro.y),
					new Point(occhioDestro.x + occhioDestro.width,
							occhioDestro.y + occhioDestro.height), new Scalar(
									50, 50, 50));
			Core.rectangle(id.getImage(), new Point(occhioSinistro.x,
					occhioSinistro.y), new Point(occhioSinistro.x
							+ occhioSinistro.width, occhioSinistro.y
							+ occhioSinistro.height), new Scalar(0, 0, 0));

			eyeDetectorR.detectMultiScale(new Mat(id.getImage(), occhioDestro),
					eyeDetections, 1.1, 3, 1, new Size(40, 40), new Size(150,
							150));
			if (eyeDetections.toArray().length != 1) {
				id.setNocchi(0);
				Core.putText(id.getImage(), "Occhi:" + id.getNocchi(),
						new Point(20, 50), 2, 0.5, new Scalar(0, 0, 0));

				return id;
			}
			rects = eyeDetections.toArray()[0];
			Rect occhio = new Rect((int) rects.tl().x,
					(int) (rects.tl().y + rects.height * 0.4),
					(int) (rects.width * 0.9), (int) (rects.height * 0.6));
			rects = occhio;
			Point init = new Point(occhioDestro.x + rects.x, occhioDestro.y
					+ rects.y);
			Point end = new Point(occhioDestro.x + rects.x + rects.width,
					occhioDestro.y + rects.y + rects.height);
			Core.rectangle(id.getImage(), init, end, new Scalar(255, 0, 0));
			id.setEyes(id.getImage().submat(rects), 0);

			eyeDetectorL.detectMultiScale(
					new Mat(id.getImage(), occhioSinistro), eyeDetections, 1.1,
					3, 1, new Size(40, 40), new Size(150, 150));
			if (eyeDetections.toArray().length != 1) {
				id.setNocchi(1);
				Core.putText(id.getImage(), "Occhi:" + id.getNocchi(),
						new Point(20, 50), 2, 0.5, new Scalar(0, 0, 0));

				return id;
			}
			rects = eyeDetections.toArray()[0];
			occhio = new Rect((int) rects.tl().x,
					(int) (rects.tl().y + rects.height * 0.4),
					(int) (rects.width * 0.9), (int) (rects.height * 0.6));
			rects = occhio;
			init = new Point(occhioSinistro.x + rects.x, occhioSinistro.y
					+ rects.y);
			end = new Point(occhioSinistro.x + rects.x + rects.width,
					occhioSinistro.y + rects.y + rects.height);
			Core.rectangle(id.getImage(), init, end, new Scalar(255, 255, 0));
			id.setEyes(id.getImage().submat(rects), 1);
			id.setNocchi(2);
		}

		return id;

	}

}